/*
 * Static.java
 *
 * Created on 4 marzo 2004, 15.29
 */

package net.ermannofranco.xml;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * Utility.
 * 
 * @author ermanno (ermanno.franco@gmail.com)
 */
public class Static {
	// da aggiornare?
	public static final String VALIDSTARTCHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_";
	public static final String VALIDCHARS = VALIDSTARTCHARS + "1234567890.:-";

	public static final String SPACE = " ";
	public static final String TWO_SPACES = "  ";
	public static final String CRLF = "\r\n";
	public static final String OPEN_COMMENT = "<!-- ";
	public static final String CLOSE_COMMENT = " -->";
	public static final String DIGITS = "1234567890";
	private static final String HEX_PREFIX = "&#x";
	public static final String TRUE = "true";
	public static final String FALSE = "false";
	public static final String COLON = ":";	

	// istanziazione proibita
	private Static() {
	}

	/**
	 * @param str
	 * @return
	 */
	public static boolean isNmToken(String str) {
		return isValidStart(str) && isValid(str);

	}

	public static boolean isOnlyDigits(String str) {
		if (str == null)
			throw new SyntaxException("argomento null non valido.");
		for (int i = 0; i < str.length(); i++) {
			if (DIGITS.indexOf(str.charAt(i)) < 0) {
				throw new SyntaxException(str.charAt(i), str);
			}
		}
		return true;

	}

	/**
	 * @param str
	 * @return
	 */
	public static char[] getInvalidChars(String str) {
		if (str == null)
			throw new SyntaxException("argomento null non valido.");
		if (isValid(str))
			return null;
		ArrayList<Character> chars = new ArrayList<Character>();
		for (int i = 0; i < str.length(); i++) {
			if (VALIDCHARS.indexOf(str.charAt(i)) == -1) {
				chars.add(str.charAt(i));
			}
		}
		if (chars.size() > 0) {
			Iterator<Character> it = chars.iterator();
			char[] ret = new char[chars.size()];
			for (int i = 0; i < ret.length; i++) {
				ret[i] = it.next().charValue();
			}
			return ret;
		}
		return null;
	}

	/**
	 * @param str
	 * @return
	 */
	private static boolean isValid(String str) {
		if (str == null)
			throw new SyntaxException("argomento null non valido.");
		for (int i = 0; i < str.length(); i++) {
			if (VALIDCHARS.indexOf(str.charAt(i)) < 0) {
				throw new SyntaxException(str.charAt(i), str);
			}
		}
		return true;
	}

	/**
	 * @param str
	 * @return
	 */
	private static boolean isValidStart(String str) {
		if (str == null)
			throw new SyntaxException("argomento null non valido.");
		if (VALIDSTARTCHARS.indexOf(str.charAt(0)) < 0) {
			throw new SyntaxException(str.charAt(0), str);
		}
		return true;
	}

	/**
	 * @param in
	 * @return
	 */
	public static String toXmlString(String in) {
		if (in == null)
			return "";
		StringBuilder out = new StringBuilder();
		for (int i = 0; i < in.length(); i++) {
			char c = in.charAt(i);
			if (c == '\"') {
				out.append("&quot;");
			} else if (c == '\'') {
				out.append("&apos;");
			} else if (c == '<') {
				out.append("&lt;");
			} else if (c == '>') {
				out.append("&gt;");
			} else if (c == '&') {
				out.append("&amp;");
			}
			// crea entita' "&#xcodiceAscii;"
			else if ((int) c > 167) {
				out.append(HEX_PREFIX).append(Integer.toHexString(c)).append(
						";");
			} else {
				out.append(c);
			}
		}
		return out.toString();
	}

	/**
	 * @param test
	 * @return
	 */
	public static boolean isMinimalStr(String test) {
		return test == null || test.length() == 0;
	}

	/**
	 * @param test
	 * @return
	 */
	public static boolean validateNMToken(String test) {
		return isNmToken(test);
	}

	/**
	 * @param test
	 * @return
	 */
	public static boolean validateID(String test) {
		return isNmToken(test);// da rivedere
	}

	public static boolean validateDigits(String test) {
		int value = Integer.parseInt(test);
		return value > 0;
	}

	/**
	 * @param sb
	 */
	public static void indent(StringBuilder sb, Indent in, int level) {
		// indentazione
		switch (in) {
		case NEWLINE_ONLY:
			sb.append(CRLF);
			break;
		case LARGE:
			sb.append(CRLF);
			for (int i = 0; i < (level * 3); i++) {
				sb.append(TWO_SPACES);
			}
			break;
		case MEDIUM:
			sb.append(CRLF);
			for (int i = 0; i < (level * 2); i++) {
				sb.append(TWO_SPACES);
			}
			break;
		case SMALL:
			sb.append(CRLF);
			for (int i = 0; i < level; i++) {
				sb.append(TWO_SPACES);
			}
			break;
		default:
			break;
		}
	}
}
